import numpy as np
from keras.layers.core import Dense, Activation, Dropout
from keras.layers.recurrent import LSTM
from keras.models import Sequential
import time
import pandas as pd

import matplotlib.pylab as plt

# 归一化
def normalization(data):
    minVals = data.min(0)
    maxVals = data.max(0)
    ranges = maxVals - minVals
    normData = np.zeros(np.shape(data))
    m = data.shape[0]
    normData = data - np.tile(minVals, (m, 1))
    normData = normData/np.tile(ranges, (m, 1))
    return normData
    # , ranges, minVals


def load_data(filename, seq_len):
    data = pd.read_excel(filename)
    np.array(data)
    data = normalization(data)
    sequence_lenghth = seq_len + 1  # 得到长度为seq_len+1的向量，最后一个作为label
    result = []
    for index in range(len(data) - sequence_lenghth):
        result.append(data[index: index + sequence_lenghth])   # 制作数据集，从data里面分割数据
    # print(result)
    result = np.array(result)
    row = round(0.8 * result.shape[0])  # round() 方法返回浮点数x的四舍五入值
    train_copy = result.copy()  # 防止浅拷贝
    np.random.shuffle(train_copy)  # shuffle() 方法将序列的所有元素随机排序。
    train = train_copy[:int(row), :]  # 取前80%
    x_train = train[:, :-1]  # 取前50列，作为训练数据
    y_train = train[:, -1]  # 取最后一列作为标签
    x_test = train_copy[int(row):, :-1]  # 取后20% 的前50列作为测试集
    y_test = train_copy[int(row):, -1]  # 取后20% 的最后一列作为标签
    # 所有的数据
    x_all = result[:, :-1]
    y_all = result[:, -1]
    x_train = np.reshape(x_train, (x_train.shape[0], x_train.shape[1], 1))  # 最后一个维度1代表一个数据的维度
    x_test = np.reshape(x_test, (x_test.shape[0], x_test.shape[1], 1))
    x_all = np.reshape(x_all, (x_all.shape[0], x_all.shape[1], 1))
    return [x_all, y_all, x_train, y_train, x_test, y_test]

def plot_results(predicted_data, true_data):
    fig = plt.figure(facecolor='white')
    ax = fig.add_subplot(111)
    ax.plot(true_data, label='True Data')
    plt.plot(predicted_data, label='Prediction')
    plt.legend()
    plt.show()

def predict_point_by_point(model, data):
    predicted = model.predict(data) # 输入测试集的全部数据进行全部预测，（412，1）
    predicted = np.reshape(predicted, (predicted.size,))
    return predicted

# 按间距中的绿色按钮以运行脚本。
if __name__ == '__main__':
    x_all, y_all, x_train, y_train, x_test, y_test = load_data('residuals.xlsx', 50)
    print('shape_x_train', np.array(x_train).shape)  # shape_x_train (3709, 50, 1)
    print('shape_y_train', np.array(y_train).shape)  # shape_y_train (3709,)
    print('shape_x_test', np.array(x_test).shape)  # shape_x_test (412, 50, 1)
    print('shape_y_test', np.array(y_test).shape)  # shape_y_test (412,)
    model = Sequential()
    model.add(LSTM(input_dim=1, units=50, return_sequences=True))
    model.add(Dropout(0.2))
    model.add(LSTM(100, return_sequences=False))
    model.add(Dropout(0.2))
    model.add(Dense(units=1))
    model.add(Activation('linear'))
    start = time.time()
    model.compile(loss='mse', optimizer='rmsprop')
    print('compilation time : ', time.time() - start)

    model.fit(x_train, y_train, batch_size=512, epochs=3, validation_split=0.05)

    predictions = predict_point_by_point(model, x_test)

    plot_results(predictions, y_test)

    predictions = predict_point_by_point(model, x_all)

    plot_results(predictions, y_all)

    # plt.plot(y_all)
    # plt.show()


